package com.one.rope.mvp.web.common.jwt;

import com.nimbusds.jose.*;
import com.nimbusds.jose.crypto.MACSigner;
import com.nimbusds.jose.crypto.MACVerifier;
import com.one.rope.mvp.basecore.util.JsonUtils;
import net.minidev.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;

/**
 * @author Weijian.liu
 * @desc json web令牌工具类
 * @date 2018/12/12
 */
public class JwtUtil {

  static Logger logger = LoggerFactory.getLogger(JwtUtil.class);

  /**
   * 初始秘钥
   */
  private static final byte[] SECRET = "465f8ad2702048db95d34abd938998c2".getBytes();

  /**
   * 初始化JWT 头
   */
  private static final JWSHeader header = new JWSHeader(JWSAlgorithm.HS256, JOSEObjectType.JWT,
      null, null, null,
      null, null, null, null, null, null, null, null);

  /**
   * 创建token
   *
   * @return token
   */
  public static String createToken(Map<String, Object> payload) {
    String tokenString = null;
    // 创建一个 JWS object
    JWSObject jwsObject = new JWSObject(header, new Payload(new JSONObject(payload)));
    try {
      // 将jwsObject 进行HMAC签名
      jwsObject.sign(new MACSigner(SECRET));
      tokenString = jwsObject.serialize();
    } catch (JOSEException e) {
      logger.error("签名失败", e);
      e.printStackTrace();
    }
    return tokenString;
  }

  /**
   * Token校验
   *
   * @return Map<String, Object>
   */
  public static PayloadBean validToken(String token) {
    try {
      JWSObject jwsObject = JWSObject.parse(token);
      Payload payload = jwsObject.getPayload();
      JWSVerifier verifier = new MACVerifier(SECRET);
      if (jwsObject.verify(verifier)) {
        JSONObject jsonOBj = payload.toJSONObject();
        String jsonString = jsonOBj.toJSONString();
        PayloadBean payloadBean = JsonUtils.stringToFasterxmlObject(jsonString, PayloadBean.class);
        if (payloadBean == null) {
          return null;
        }
        /**
         * 超时验证
         */
        long currentTimes = System.currentTimeMillis();
        if (currentTimes > (payloadBean.getCreateTime() + payloadBean.getExpires())) {
          payloadBean.setTokenState(TokenState.EXPIRED);
        }
        return payloadBean;
      } else {
        return null;
      }
    } catch (Exception e) {
      return null;
    }
  }

  public static void main(String[] args) {

  }
}
